import { useCallback, useEffect, useRef, useState } from 'react'

import { useAppSelector } from '@/redux/store'

import type { Top5WarnDataItem } from '../data'

// const socketUrl = "ws://p998.ops.logibeat.com:5555"

const socketUrl =
  window.location.origin.indexOf('mp.yunmai56.com') > -1
    ? 'ws://10.111.118.215:5555' //正式
    : 'ws://p998.ops.logibeat.com:5555' //预发

interface SocketTop5WarnDataItem extends Top5WarnDataItem {
  type: 'getBigScreenWData'
  personId: string
  entId: string
  timeMap: number
  uid?: string
}

interface UseBgWarnScoketProps {
  entId: string
}

interface UseBgWarnScoketReturn {
  bgWarnSocketData?: Top5WarnDataItem
  connectWebSocket: () => void
  clearWebScoket: () => void
}

function useBgWarnScoket(props: UseBgWarnScoketProps): UseBgWarnScoketReturn {
  const { entId } = props
  //获取当前用户ID
  const { personId, timeMap } = useAppSelector((state) => state.loginUser)
  // console.log('--useBgWarnScoket--personId---:', personId);
  const errorLinkCountRef = useRef<number>(0)
  const errorTimeoutIdRef = useRef<any>() //socket连接错误时，每隔5s重连
  const webSocketRef = useRef<any>(null)

  const pingTimeoutIdRef = useRef<any>()

  const [bgWarnSocketData, setBgWarnSocketData] = useState<
    Top5WarnDataItem | undefined
  >()

  //连接
  const connectWebSocket = useCallback(() => {
    try {
      if (errorLinkCountRef.current >= 5) {
        if (errorTimeoutIdRef.current) {
          clearInterval(errorTimeoutIdRef.current)
        }
      } else {
        errorLinkCountRef.current += 1
      }
      console.warn('===BigscreenWarn websocket连接中===')
      if (!webSocketRef.current) {
        webSocketRef.current = new WebSocket(socketUrl)
      }
      //开启连接
      webSocketRef.current.onopen = (event: any) => {
        errorLinkCountRef.current = 0
        if (errorTimeoutIdRef.current) {
          clearTimeout(errorTimeoutIdRef.current)
        }
        console.warn('===BigscreenWarn websocket 连接已打开===')
        // 发送消息
        const message = JSON.stringify({
          type: 'insertBigScreenWarn',
          personId,
          entId,
          timeMap
        })
        webSocketRef.current.send(message)
      }

      //接收消息
      webSocketRef.current.onmessage = (event: any) => {
        if (event.data) {
          const dataObj: SocketTop5WarnDataItem = JSON.parse(event.data)
          console.warn(
            'BigscreenWarn websocket收到服务端消息event.data：',
            dataObj.alermName
          )
          const {
            type,
            personId: sPersonId,
            entId: sEntdId,
            uid,
            ...restProps
          } = dataObj ?? {}
          const combineKey = sEntdId + '_' + sPersonId + '_' + timeMap
          if (type === 'getBigScreenWData' && combineKey === uid) {
            setBgWarnSocketData(restProps)
          }
        }
      }

      // 客户端监听到服务端发送过来的ping就取消断联,否则35s之后断联
      webSocketRef.current.onping = _heartbeat

      webSocketRef.current.onclose = (event: any) => {
        console.warn('BigscreenWarn WebSocket onclose')
      }

      //触发onerror的同时也会触发onclose，且这两者都只会触发一次
      webSocketRef.current.onerror = (error: any) => {
        console.error('SocketTest WebSocket 连接失败 onerror--:', error)
        errorTimeoutIdRef.current = setInterval(connectWebSocket, 5000) // 5秒后尝试重新连接
        errorLinkCountRef.current += 1
      }
    } catch (error) {
      console.error('WebSocket 创建失败:', error)
    }
  }, [entId])

  function _heartbeat() {
    console.warn('---监听到服务端发送过来的ping，取消35s后断开连接---')
    if (pingTimeoutIdRef.current) {
      clearTimeout(pingTimeoutIdRef.current)
    }
    pingTimeoutIdRef.current = setTimeout(() => {
      if (webSocketRef.current) {
        console.warn('---未监听到服务端发送过来的ping,断开连接----')
        webSocketRef.current.terminate()
      }
    }, 35000)
  }

  //关闭
  const clearWebScoket = () => {
    console.warn('===BigscreenWarn websocket断开连接===')
    setBgWarnSocketData(undefined)
    errorLinkCountRef.current = 0
    if (errorTimeoutIdRef.current) {
      clearInterval(errorTimeoutIdRef.current)
    }
    if (webSocketRef.current && webSocketRef.current.readyState === 1) {
      //是开启状态
      webSocketRef.current.send(
        JSON.stringify({
          type: 'outBigScreenWarn',
          personId,
          entId,
          timeMap
        })
      )

      webSocketRef.current.close()
      webSocketRef.current = undefined
    }
  }

  useEffect(() => {
    // if (!personId) return
    // connectWebSocket()
    // return () => {
    //   clearWebScoket()
    // }
    window.addEventListener('beforeunload', clearWebScoket) //关闭浏览器时
    return () => {
      window.removeEventListener('beforeunload', clearWebScoket)
    }
  }, [])

  return {
    bgWarnSocketData,
    clearWebScoket,
    connectWebSocket
  }
}

export default useBgWarnScoket
